//===============================================================================
// Microsoft patterns & practices
// Web Client Software Factory
//-------------------------------------------------------------------------------
// Copyright (C) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//-------------------------------------------------------------------------------
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================
using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Workflow.Runtime;
using WCSFContrib.PageFlow.WorkflowFoundation.Tests.Mocks;
using System.Workflow.Activities;
using WCSFContrib.PageFlow.WorkflowFoundation.Activities;
using System.Collections.ObjectModel;
using System.Workflow.Runtime.Hosting;


namespace WCSFContrib.PageFlow.WorkflowFoundation.Tests
{
    /// <summary>
    /// Summary description for StateMachineQuery
    /// </summary>
    [TestClass]
    public class StateMachineQueryFixture
    {
        [ClassInitialize]
        public static void SetupDatabase(TestContext testContext)
        {
            SetupDatabaseUtility.Setup();
        }

        [TestMethod]
        public void GetInstanceQueueDataAvailable()
        {
            using (WorkflowRuntime runtime = new WorkflowRuntime("pageFlow/hostingWorkflowRuntime"))
            {
                runtime.StartRuntime();
                WorkflowInstance instance = runtime.CreateWorkflow(typeof(MockConstrainedPageFlow));
                instance.Start();
                RunWorkflow(instance);
                StateMachineQuery query = new StateMachineQuery((StateMachineWorkflowActivity)instance.GetWorkflowDefinition(), instance);

                Assert.IsTrue(query.IsWorkflowQueueDataAvailable());
            }
        }

        [TestMethod]
        public void GetInstanceQueueDataNotAvailable()
        {
            using (WorkflowRuntime runtime = new WorkflowRuntime("pageFlow/hostingWorkflowRuntime"))
            {
                runtime.StartRuntime();
                WorkflowInstance instance = runtime.CreateWorkflow(typeof(MockConstrainedPageFlow));
                StateMachineQuery query = new StateMachineQuery((StateMachineWorkflowActivity)instance.GetWorkflowDefinition(), instance);

                Assert.IsFalse(query.IsWorkflowQueueDataAvailable());
            }
        }

        [TestMethod]
        public void GetNullCurrentStateWhenInstanceIsJustStarted()
        {
            using (WorkflowRuntime runtime = new WorkflowRuntime("pageFlow/hostingWorkflowRuntime"))
            {
                runtime.StartRuntime();
                WorkflowInstance instance = runtime.CreateWorkflow(typeof(MockConstrainedPageFlow));
                instance.Start();
                StateMachineQuery query = new StateMachineQuery((StateMachineWorkflowActivity)instance.GetWorkflowDefinition(), instance);

                Assert.IsNull(query.CurrentState);

            }
        }

        [TestMethod]
        public void GetInitialStateWhenCallingGetCurrentStateOnAStartedInstance()
        {
            using (WorkflowRuntime runtime = new WorkflowRuntime("pageFlow/hostingWorkflowRuntime"))
            {
                runtime.StartRuntime();
                WorkflowInstance instance = runtime.CreateWorkflow(typeof(MockConstrainedPageFlow));
                instance.Start();
                RunWorkflow(instance);
                StateMachineQuery query = new StateMachineQuery((StateMachineWorkflowActivity)instance.GetWorkflowDefinition(), instance);

                Assert.AreEqual("PageA", query.CurrentState.QualifiedName);
            }
        }

        [TestMethod]
        public void CurrentStateGetsNextStateWhenEventIsRaised()
        {
            using (WorkflowRuntime runtime = new WorkflowRuntime("pageFlow/hostingWorkflowRuntime"))
            {
                runtime.StartRuntime();
                WorkflowInstance instance = runtime.CreateWorkflow(typeof(MockConstrainedPageFlow));
                instance.Start();
                RunWorkflow(instance);
                StateMachineQuery query = new StateMachineQuery((StateMachineWorkflowActivity)instance.GetWorkflowDefinition(), instance);

                // transition to B
                instance.EnqueueItem("GOTOB", "goToB", null, null);
                RunWorkflow(instance);

                Assert.AreEqual("PageB", query.CurrentState.QualifiedName);

            }
        }

        [TestMethod]
        public void SetStateChangesStateMachineCurrentState()
        {
            using (WorkflowRuntime runtime = new WorkflowRuntime("pageFlow/hostingWorkflowRuntime"))
            {
                runtime.StartRuntime();
                WorkflowInstance instance = runtime.CreateWorkflow(typeof(MockConstrainedPageFlow));
                instance.Start();
                RunWorkflow(instance);
                StateMachineQuery query = new StateMachineQuery((StateMachineWorkflowActivity)instance.GetWorkflowDefinition(), instance);

                // transition to B
                query.SetState("PageB");
                RunWorkflow(instance);

                Assert.AreEqual("PageB", query.CurrentState.QualifiedName);

            }
        }

        [TestMethod]
        public void GetCurrentStateNameReturnsStateActivityQualfiedName()
        {
            using (WorkflowRuntime runtime = new WorkflowRuntime("pageFlow/hostingWorkflowRuntime"))
            {
                runtime.StartRuntime();
                WorkflowInstance instance = runtime.CreateWorkflow(typeof(MockConstrainedPageFlow));
                instance.Start();
                RunWorkflow(instance);
                StateMachineQuery query = new StateMachineQuery((StateMachineWorkflowActivity)instance.GetWorkflowDefinition(), instance);

                Assert.AreSame(query.CurrentStateName, query.CurrentState.QualifiedName);
                Assert.AreEqual("PageA", query.CurrentStateName);
            }
        }

        private void RunWorkflow(WorkflowInstance instance)
        {
            ManualWorkflowSchedulerService workflowScheduler =
                instance.WorkflowRuntime.GetService<ManualWorkflowSchedulerService>();
            workflowScheduler.RunWorkflow(instance.InstanceId);
        }
    }
}
